from pydantic import BaseModel, Field, ConfigDict
from typing import Generic, TypeVar, Optional, Any, Dict, Union
import json
import datetime
from app.exception.error_code import ErrorCode

T = TypeVar('T')
SUCC: int = 0  # 成功状态码
FAIL: int = 100  # 默认失败状态码

class RR(BaseModel, Generic[T]):
    """通用响应模型，泛型设计"""
    model_config = ConfigDict(
        json_encoders={
            # 自定义日期时间序列化格式
            datetime.datetime: lambda v: v.strftime("%Y-%m-%d %H:%M:%S"),
            datetime.date: lambda v: v.strftime("%Y-%m-%d"),
        },
        # 允许额外字段，提高兼容性
        extra="allow"
    )
    
    code: int = Field(default=SUCC, description="状态码")
    msg: Optional[str] = Field(default="操作成功", description="响应消息")
    data: Optional[T] = Field(default=None, description="响应数据")
    timestamp: Optional[int] = Field(
        default_factory=lambda: int(datetime.datetime.now().timestamp() * 1000), 
        description="响应时间戳（毫秒）"
    )
    
    def __init__(self, **data):
        # 直接调用父类初始化方法
        super().__init__(**data)
    
    @classmethod
    def success(cls, data: Any = None, msg: str = "操作成功") -> 'RR[T]':
        """创建成功响应
        
        Args:
            data: 响应数据，默认为None
            msg: 响应消息，默认为"操作成功"
            
        Returns:
            RR[T]: 成功响应对象
        """
        return cls(code=SUCC, msg=msg, data=data)
    
    @classmethod
    def fail(cls, msg: str = "操作失败", code: int = FAIL, data: Any = None) -> 'RR[T]':
        """创建失败响应
        
        Args:
            msg: 错误消息，默认为"操作失败"
            code: 错误码，默认为FAIL
            data: 附加数据，默认为None
            
        Returns:
            RR[T]: 失败响应对象
        """
        return cls(code=code, msg=msg, data=data)
    
    @classmethod
    def from_exception(cls, exc: Exception, code: int = ErrorCode.SYSTEM_ERROR) -> 'RR[Any]':
        """从异常创建响应对象
        
        Args:
            exc: 异常对象
            code: 错误码，默认为系统错误
            
        Returns:
            RR[Any]: 失败响应对象
        """
        # 处理CodeException
        if hasattr(exc, 'code') and hasattr(exc, 'err_msg'):
            return cls.fail(msg=exc.err_msg, code=exc.code, data=getattr(exc, 'data', None))
        # 处理标准异常
        return cls.fail(msg=str(exc), code=code)
    
    def is_success(self) -> bool:
        """判断响应是否成功
        
        Returns:
            bool: 成功返回True，失败返回False
        """
        return self.code == SUCC
    
    def is_fail(self) -> bool:
        """判断响应是否失败
        
        Returns:
            bool: 失败返回True，成功返回False
        """
        return not self.is_success()
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典
        
        Returns:
            Dict[str, Any]: 响应字典
        """
        # 移除为None的字段
        return {k: v for k, v in self.model_dump().items() if v is not None}
    
    def __str__(self) -> str:
        """字符串表示"""
        status = "SUCCESS" if self.is_success() else "FAILURE"
        return f"RR({status}, code={self.code}, message={self.message})"


class RRString(RR[str]):
    """字符串响应模型"""
    
    @classmethod
    def from_string(cls, output: str, raise_on_error: bool = True) -> 'RRString':
        """从字符串创建响应对象
        
        Args:
            output: 字符串输出
            raise_on_error: 失败时是否抛出异常，默认为True
            
        Returns:
            RRString: 响应对象
            
        Raises:
            Exception: 当响应不是成功状态且raise_on_error为True时
        """
        try:
            # 尝试解析JSON
            json_data = json.loads(output)
            
            # 确保是字典格式
            if not isinstance(json_data, dict):
                raise ValueError(f"Invalid response format: {output}")
            
            # 解析为响应对象
            rr = cls(**json_data)
            
            # 根据配置决定是否在失败时抛出异常
            if raise_on_error and not rr.is_success():
                raise ValueError(rr.message or "操作失败")
            
            return rr
        except json.JSONDecodeError:
            # JSON解析失败
            error_msg = f"Failed to parse JSON: {output}"
            if raise_on_error:
                raise ValueError(error_msg)
            return cls.fail(message=error_msg)
    
    @classmethod
    def from_rr(cls, rr: RR[Any]) -> 'RRString':
        """从RR对象创建RRString
        
        Args:
            rr: 任意类型的RR对象
            
        Returns:
            RRString: 字符串响应对象
        """
        # 将data字段转换为字符串
        data_str = str(rr.data) if rr.data is not None else None
        return cls(code=rr.code, message=rr.message, data=data_str)


class SuccessView(RR[Dict[str, Any]]):
    """成功视图模型"""
    
    @classmethod
    def create(cls, message: str = "操作成功", data: Any = None) -> 'SuccessView':
        """创建默认成功视图
        
        Args:
            message: 自定义成功消息，默认为"操作成功"
            data: 附加数据，默认为None
            
        Returns:
            SuccessView: 成功视图对象
        """
        return cls(code=SUCC, message=message, data=data)